package com.tuanchau.android.englishtooltip.ui.activity;

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnKeyListener;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import com.tuanchau.android.englishtooltip.EnglishToolTipApplication;
import com.tuanchau.android.englishtooltip.Global;
import com.tuanchau.android.englishtooltip.R;
import com.tuanchau.android.englishtooltip.database.ScaleWord;
import com.tuanchau.android.englishtooltip.database.XMLProcess;

public class EditWordActivity extends Activity implements OnClickListener,
		OnKeyListener, OnFocusChangeListener {

	private static final int SELECT_IMAGE = 101;

	private ImageView imageView;
	private EditText txtWord;
	private TextView txtPronunciation;
	private Spinner spnType;

	private TextView txtMean;

	private String strWord, strMean, strPronunciation, strType;
	private byte[] image;

	private Bitmap bitmap;

	private int state;

	private int countThread = 0;

	private String[] arrWord;
	private String[] arrPon;

	private Handler handler;

	private URL url;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_edit_word);

		handler = new Handler();
		initPronList();
		initView();
		arrWord = EnglishToolTipApplication.listWord;
		arrPon = EnglishToolTipApplication.listPron;
	}

	private void initView() {
		Bundle bundle = getIntent().getExtras();

		imageView = (ImageView) findViewById(R.id.activity_edit_word_image);

		txtPronunciation = (TextView) findViewById(R.id.activity_edit_word_pronunciation);
		Typeface font = Typeface
				.createFromAsset(getAssets(), "courier_new.ttf");
		txtPronunciation.setTypeface(font);

		txtMean = (EditText) findViewById(R.id.activity_edit_word_mean);
		spnType = (Spinner) findViewById(R.id.activity_edit_word_type);

		txtWord = (EditText) findViewById(R.id.activity_edit_word_word);

		state = bundle.getInt(Global.STATE_CODE);

		if (state == Global.STATE_EDIT) {
			strWord = bundle.getString(Global.KEY_WORD);
			strMean = bundle.getString(Global.KEY_MEAN);
			image = bundle.getByteArray(Global.KEY_IMAGE);
			strPronunciation = bundle.getString(Global.KEY_PRONUNCIATION);
			strType = bundle.getString(Global.KEY_TYPE);

			txtWord.setText(strWord);
			txtMean.setText(strMean);
			if (strPronunciation.length() > 0)
				txtPronunciation.setText("/" + strPronunciation + "/");
			int position = findWordType(strType);
			spnType.setSelection(position);
			setImage(image);
		} else if (state == Global.STATE_NEWWORD) {
			boolean isFirst = bundle.getBoolean(Global.KEY_FIRSTWORD);
			if (isFirst) {
				// findViewById(R.id.activity_edit_word_cancel).setEnabled(false);

			}
		}

		findViewById(R.id.activity_edit_word_autofill).setOnClickListener(this);
		findViewById(R.id.activity_edit_word_store).setOnClickListener(this);
		findViewById(R.id.activity_edit_word_cancel).setOnClickListener(this);

		imageView.setOnClickListener(this);
		txtWord.setOnFocusChangeListener(this);
		txtWord.addTextChangedListener(new TextWatcher() {

			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
				// doPrepareToGetPronunciation();
				String str = txtWord.getText().toString();
				if (str.length() > 0) {

					txtPronunciation.setText("/"
							+ doGetPronunciation(str).trim() + "/");
				} else {
					txtPronunciation.setText("");
				}

			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {

			}

			@Override
			public void afterTextChanged(Editable s) {

			}
		});
	}

	private void initPronList() {
		if (EnglishToolTipApplication.listWord == null) {
			try {
				BufferedReader reader = new BufferedReader(
						new InputStreamReader(getAssets().open("pron_data.txt")));
				String line = reader.readLine();
				int length = Integer.parseInt(line);
				EnglishToolTipApplication.listPron = new String[length];
				EnglishToolTipApplication.listWord = new String[length];

				line = reader.readLine();
				int count = 0;
				String[] arr;
				while (line != null) {
					arr = line.split("\t");
					EnglishToolTipApplication.listWord[count] = arr[0];
					EnglishToolTipApplication.listPron[count] = arr[1];
					count++;
					line = reader.readLine();
				}

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	private void setImage(byte[] image) {
		if (image != null) {
			bitmap = BitmapFactory.decodeByteArray(image, 0, image.length);
			imageView.setImageBitmap(bitmap);
		} else {
			imageView.setImageResource(R.drawable.english_tip_icon_100);
		}
	}

	private void setImage(String path) {
		if (path != null) {
			File file = new File(path);
			if (file.exists()) {
				bitmap = scaleImage(path);
				imageView.setImageBitmap(bitmap);
			} else {
				imageView.setImageResource(R.drawable.english_tip_icon_100);
			}
		} else {
			imageView.setImageResource(R.drawable.english_tip_icon_100);
		}

	}

	private int findWordType(String type) {
		String[] arr = getResources().getStringArray(R.array.word_types);
		for (int i = 0; i < arr.length; i++) {
			if (type.equals(arr[i]))
				return i;
		}
		return 0;
	}

	@Override
	public void onClick(View btn) {
		switch (btn.getId()) {
		case R.id.activity_edit_word_autofill:
			onAutoGetMeanClicked();
			break;
		case R.id.activity_edit_word_store:
			onStoreClicked();
			break;
		case R.id.activity_edit_word_cancel:
			onCancelClicked();
			break;
		case R.id.activity_edit_word_image:
			onImageViewClicked();
			break;
		default:
			break;
		}

	}

	private void onAutoGetMeanClicked() {
		if (checkNetworkAvailble()) {
			final ProgressDialog progressDialog = ProgressDialog.show(this, "",
					"Please wait...", true);
			final Handler handlerProgressDialog = new Handler() {
				@Override
				public void handleMessage(Message msg) {
					progressDialog.dismiss();
				}
			};

			final Handler handlerUpdateUI = new Handler();

			Thread threadGetMean = new Thread() {
				@Override
				public void run() {
					final String word = txtWord.getText().toString();
					String str = connectAndGet(word);

					final ScaleWord[] sw = XMLProcess.parseWordFromXml(str);
					if (sw == null) {
						handlerUpdateUI.post(new Runnable() {

							@Override
							public void run() {
								Toast.makeText(EditWordActivity.this,
										word + " is not found",
										Toast.LENGTH_LONG).show();
							}
						});

					} else {
						handlerUpdateUI.post(new Runnable() {

							@Override
							public void run() {
								ChooseWordDialog dialog = new ChooseWordDialog(
										EditWordActivity.this, word, sw);
								dialog.show();
							}
						});

					}

					handlerProgressDialog.sendEmptyMessage(0);
				}
			};
			threadGetMean.start();

		} else {
			Toast.makeText(this, "Network is not available", Toast.LENGTH_SHORT)
					.show();
		}

	}

	private String connectAndGet(String word) {
		String result = "";
		if (!word.equals("")) {
			try {
				if (url == null) {
					url = new URL("http://englishtooltip.appspot.com/tip");
				}
				HttpURLConnection con = (HttpURLConnection) url
						.openConnection();
				con.setRequestMethod("POST");
				con.setDoOutput(true);
				OutputStreamWriter writer = new OutputStreamWriter(
						con.getOutputStream());
				writer.write("action=3&w=" + word);
				writer.flush();
				BufferedReader reader = null;
				try {
					reader = new BufferedReader(new InputStreamReader(
							con.getInputStream(), "UTF-8"));
				} catch (Exception e) {
					reader = new BufferedReader(new InputStreamReader(
							con.getInputStream(), "UTF8"));
				}
				String line = reader.readLine();

				while (line != null) {
					result += line;
					line = reader.readLine();
				}

			} catch (IOException e) {
				e.printStackTrace();
			}

		}
		return result;
	}

	private boolean checkNetworkAvailble() {
		ConnectivityManager conm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
		if (conm == null) {
			Toast.makeText(this, "Check Network fail", Toast.LENGTH_LONG)
					.show();

		} else {
			NetworkInfo[] info = conm.getAllNetworkInfo();
			if (info != null) {
				for (int i = 0; i < info.length; i++) {
					if (info[i].getState() == NetworkInfo.State.CONNECTED) {
						return true;
					}
				}
			}
		}

		return false;
	}

	public void setMean(String type, String mean) {
		txtMean.setText(mean);
		if (type.equals("noun")) {
			spnType.setSelection(0);
		} else if (type.equals("verb")) {
			spnType.setSelection(1);
		} else if (type.equals("adjective")) {
			spnType.setSelection(2);
		} else if (type.equals("adverb")) {
			spnType.setSelection(3);
		} else if (type.equals("preposition")) {
			spnType.setSelection(4);
		} else {
			spnType.setSelection(5);
		}
	}

	private void onStoreClicked() {
		strWord = txtWord.getText().toString().trim();
		if (strWord.equals("")) {
			Toast.makeText(this, getString(R.string.toast_enter_word_first),
					Toast.LENGTH_SHORT).show();
		} else {
			strMean = txtMean.getText().toString().trim();
			String arr[] = getResources().getStringArray(R.array.word_types);
			strType = arr[spnType.getSelectedItemPosition()];
			if (bitmap != null) {
				ByteArrayOutputStream bos = new ByteArrayOutputStream();
				bitmap.compress(Bitmap.CompressFormat.PNG, 90, bos);
				image = bos.toByteArray();
			}
			String strPron = txtPronunciation.getText().toString();
			if (strPron != null && strPron.length() > 2) {
				strPronunciation = strPron.substring(1, strPron.length() - 1);
			}

			Intent result = new Intent();
			result.putExtra(Global.STATE_CODE, state);
			result.putExtra(Global.KEY_WORD, strWord);
			result.putExtra(Global.KEY_MEAN, strMean);
			result.putExtra(Global.KEY_PRONUNCIATION, strPronunciation);
			result.putExtra(Global.KEY_TYPE, strType);
			result.putExtra(Global.KEY_IMAGE, image);

			setResult(Activity.RESULT_OK, result);

			// getSharedPreferences(Global.PREF_SETTING_FILE_NAME, MODE_PRIVATE)
			// .edit().putBoolean(Global.PREF_KEY_UPDATE_WORD, true)
			// .commit();

			finish();
		}

	}

	private void onCancelClicked() {
		Intent result = new Intent();
		result.putExtra(Global.STATE_CODE, Global.STATE_NOCHANGE);
		setResult(Activity.RESULT_OK, result);

		finish();
	}

	private void onImageViewClicked() {
		Intent intent = new Intent();
		intent.setType("image/*");
		intent.setAction(Intent.ACTION_GET_CONTENT);
		startActivityForResult(Intent.createChooser(intent,
				getString(R.string.title_chooser_image)), SELECT_IMAGE);
	}

	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode == RESULT_OK) {
			if (requestCode == SELECT_IMAGE) {
				Uri selectedImageUri = data.getData();
				String imagePath = getImagePath(selectedImageUri);
				setImage(imagePath);

			}
		}
	}

	public String getImagePath(Uri uri) {
		String[] projection = { MediaStore.Images.Media.DATA };
		Cursor cursor = managedQuery(uri, projection, null, null, null);
		int column_index = cursor
				.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
		cursor.moveToFirst();
		return cursor.getString(column_index);
	}

	@Override
	protected void onStop() {
		super.onStop();
	}

	private Bitmap scaleImage(String imgFile) {
		final int standarSize = 100;
		BitmapFactory.Options o = new BitmapFactory.Options();
		o.inTempStorage = new byte[16 * 1024];

		Bitmap bitmapOrg;
		bitmapOrg = BitmapFactory.decodeFile(imgFile, o);
		int width = bitmapOrg.getWidth();
		int height = bitmapOrg.getHeight();
		int size = Math.min(width, height);

		int x = Math.abs(width / 2 - size / 2);
		int y = Math.abs(height / 2 - size / 2);
		float scaleRatio = ((float) standarSize / size);

		Matrix matrix = new Matrix();
		matrix.postScale(scaleRatio, scaleRatio);

		Bitmap resizeBitmap = Bitmap.createBitmap(bitmapOrg, x, y, size, size,
				matrix, true);

		return resizeBitmap;
	}

	private Bitmap createRoundBitmap(Bitmap bitmap, int roundPixels) {
		final int bitWidth = bitmap.getWidth();
		final int bitHeight = bitmap.getHeight();
		Bitmap tmpBimap = Bitmap.createBitmap(bitWidth, bitHeight,
				Config.ARGB_8888);
		Canvas canvas = new Canvas(tmpBimap);

		final int color = 0xffffffff;
		final Paint paint = new Paint();
		final Rect rect = new Rect(0, 0, bitWidth, bitHeight);
		final RectF rectF = new RectF(rect);
		final float roundPx = roundPixels;

		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);

		// canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

		canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));

		canvas.drawBitmap(bitmap, rect, rect, paint);

		return tmpBimap;
	}

	@Override
	public boolean onKey(View v, int keyCode, KeyEvent event) {

		doPrepareToGetPronunciation();

		return false;
	}

	private void doPrepareToGetPronunciation() {
		Thread thr = new Thread(new Runnable() {
			@Override
			public void run() {
				countThread++;
				String str = txtWord.getText().toString();
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				final String newStr = txtWord.getText().toString();
				if (str.equals(newStr)) {
					if (countThread <= 1) {
						strPronunciation = doGetPronunciation(newStr).trim();
						if (newStr.length() > 0) {
							handler.post(new Runnable() {

								@Override
								public void run() {

									txtPronunciation.setText("/"
											+ strPronunciation + "/");

								}
							});

						}
					} else {
					}
				} else {
				}
				countThread--;

			}
		});

		thr.start();
	}

	private String doGetPronunciation(String word) {
		String[] arr = word.split(" ");
		String result = "";
		for (String w : arr) {
			result += findPron(w) + " ";
		}
		return result;
	}

	private String findPron(String word) {
		int min = 0;
		int max = arrWord.length - 1;
		int mid = (min + max) / 2;
		int comp = word.compareTo(arrWord[mid]);
		int count = 0;
		while (min <= max) {
			if (count > 30) {
				break;
			}
			if (comp < 0) {
				max = mid - 1;
				mid = (min + max) / 2;
				comp = word.compareTo(arrWord[mid]);
			} else if (comp > 0) {
				min = mid + 1;
				mid = (min + max) / 2;
				comp = word.compareTo(arrWord[mid]);
			} else {
				// Log.d("Edit word" , "con heo : result = " + arrPon[mid]);
				return arrPon[mid];
			}
		}

		return word;
	}

	@Override
	public void onFocusChange(View view, boolean hasFocus) {

	}

}
